﻿using Caliburn.Micro;
using MCPlatform.Builder.WorkStation;
using MCPlatform.Builder.WorkStation.StationEvents;
using MCPlatform.Builder.WorkStation.StationEvents.Home;
using MCPlatform.Builder.WorkStation.StationEvents.MainControl;
using MCPlatform.Components.Utilities;
using MCPlatform.Models;
using MCPlatform.Shared.DAL.Contexts;
using MCPlatform.Shared.DAL.Models;
using MCPlatform.Shared.Enums;
using MCPlatform.Shared.Enums.Modes;
using MCPlatform.UI.Components;
using MCPlatform.UI.Resources.Languages;
using MCPlatform.ViewModels.Dxf;
using MCPlatform.ViewModels.Motion;
using MCPlatform.ViewModels.Product;
using Panuon.WPF.UI;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Media;
using MCPlatform.MachineFSM;
using MCPlatform.MachineFSM.States;


namespace MCPlatform.ViewModels.Shell
{
    [Serializable]
    public class HomeViewModel : ViewModelBase,IHandle<MainControlToHomeEvent>
    {
        #region Fields

        private bool isRunning = false;

        private bool isPause = false;

        private CADViewModel CADViewModel = new CADViewModel();

        System.Timers.Timer timer = new System.Timers.Timer(1000);

        private Stopwatch _productTimerStopwatch = new Stopwatch();

        private Stopwatch _totalTimerStopwatch = new Stopwatch();

        private DateTime _startTime = DateTime.Now;

        private FSM _fsm;

      //  private Blackboard _blackboard = new Blackboard();


        private Dictionary<int,AxisViewModel> _axisViewModelDic = new Dictionary<int, AxisViewModel>();
        private Dictionary<int, ValveViewModel> _valveViewModelDic = new Dictionary<int, ValveViewModel>();
        private Dictionary<int, IOViewModel> _iOViewModelDic = new Dictionary<int, IOViewModel>();
        private Dictionary<int, StationSettingViewModel> _StationSettingViewModelDic = new Dictionary<int, StationSettingViewModel>();
        private Dictionary<int, PointsViewModel> _pointsViewModelDic = new Dictionary<int, PointsViewModel>();
        private Dictionary<int, CoordinateViewModel> _coordinateViewModelDic = new Dictionary<int, CoordinateViewModel>();


        #endregion

        #region properties



        /// <summary>
        /// 工站字典
        /// </summary>
        public Dictionary<int, WorkStationModel> WorkStationDic { get => _WorkStationDic; set => Set(ref _WorkStationDic, value); }
        private Dictionary<int, WorkStationModel> _WorkStationDic = new Dictionary<int, WorkStationModel>();

        public ObservableCollection<bool> BufferTrayItems { get => _BufferTrayItems; set => Set(ref _BufferTrayItems, value); }
        private ObservableCollection<bool> _BufferTrayItems = new ObservableCollection<bool>() { false,false,false,false,false};
        public Dictionary<int, IStation> StationDic { get => _StationDic; set => Set(ref _StationDic, value); }
        private Dictionary<int, IStation> _StationDic = new Dictionary<int, IStation>();

        /// <summary>
        /// 日志列表
        /// </summary>
        public ObservableCollection<LogModel> LogList { get => _LogList; set => Set(ref _LogList, value); }
        private ObservableCollection<LogModel> _LogList = new ObservableCollection<LogModel>();


        /// <summary>
        /// 码垛数量
        /// </summary>
        public uint StackCount
        {
            get => _StackCount;
            set
            {
                Set(ref _StackCount, value);
                if (UnloadStation.Instance.UnloadNumber != value)
                {
                    if (User is null || User.Equals("Operator"))
                    {
                        Toast.Show("权限不足！",targetWindow:ToastWindow.MainWindow);
                        Set(ref _StackCount, UnloadStation.Instance.UnloadNumber);
                        return;
                    }
                    else if (value > (uint)ProductInfo.GetUnloadMaxNumber())
                    {
                        Toast.Show("数字超过码垛最大值！", targetWindow: ToastWindow.MainWindow);
                        Set(ref _StackCount, UnloadStation.Instance.UnloadNumber);
                        return;
                    }
                    UnloadStation.Instance.UnloadNumber = value;
                }
                
            }
                
        }
        private uint _StackCount = 0;


        /// <summary>
        /// 生产数量
        /// </summary>
        public uint ProductionCount
        {
            get => _ProductionCount;
            set
            {
                Set(ref _ProductionCount, value);
               

            }

        }
        private uint _ProductionCount = 0;


        /// <summary>
        /// 最大码垛数量
        /// </summary>
        public double StackMaxNumber { get => _StackMaxNumber; set => Set(ref _StackMaxNumber, value); }
        private double _StackMaxNumber = (double)ProductInfo.GetUnloadMaxNumber();


        /// <summary>
        /// 良率
        /// </summary>
        public double PassRate { get => _PassRate; set => Set(ref _PassRate, value); }
        private double _PassRate = 100;

        /// <summary>
        /// 生产率
        /// </summary>
        public double OEE { get => _OEE; set => Set(ref _OEE, value); }
        private double _OEE = 90;


        /// <summary>
        /// 节拍
        /// </summary>
        public int UPH { get => _UPH; set => Set(ref _UPH, value); }
        private int _UPH = 0;


        public string TotalTimer { get => _TotalTimer; set => Set(ref _TotalTimer, value); }
        private string _TotalTimer = "00:00:00";


        public string ProductTimer { get => _ProductTimer; set => Set(ref _ProductTimer, value); }
        private string _ProductTimer = "00:00:00";


        public  AutomaticSubMode AutomaticSubModeObservable
        {
            get => _automaticSubModeObservable;
            set
            {
                Set(ref _automaticSubModeObservable, value);
            }
        }
        private  AutomaticSubMode _automaticSubModeObservable;


        public ButtonModel StartButtonModel { get => _StartButtonModel; set => Set(ref _StartButtonModel, value); }
        private ButtonModel _StartButtonModel = new ButtonModel() { Content = "启动", BackBrush = Brushes.LightGreen };

        public ButtonModel PauseButtonModel { get => _PauseButtonModel; set => Set(ref _PauseButtonModel, value); }
        private ButtonModel _PauseButtonModel = new ButtonModel() { Content = "暂停", BackBrush = Brushes.Orange };


        public ButtonModel ClearButtonModel { get => _ClearButtonModel; set => Set(ref _ClearButtonModel, value); }
        private ButtonModel _ClearButtonModel = new ButtonModel() { Content = "清料", BackBrush = Brushes.LightBlue };


        private bool isResuming;
        private CancellationToken cancellationToken = new CancellationToken();
        public bool IsInitialing { get; set; } = false;

        public bool IsInitialed { get; set; } = false;

        public   bool IsClearling { get; set; } = false;

        public   int ClearTimes { get; set; } = 0;

        public bool IsSingleCycleHeld { get; set; }

        #endregion

        #region Event

        //  public static event Action<bool,int>? ClearEvent;

        public static event Func<bool>? ResetEvent;

        public static event Func<bool>? SafetyOptpEvent;

     


        #endregion

        #region ctor
        public HomeViewModel()
        {
          
            WorkStationDic = WorkStation.Instance.WorkStationDic;

            StationDic.Add(0, MainControlStation.Instance);

            StationDic.Add(1,  LoadStation.Instance);
          
            StationDic.Add(2,  CuttingStation.Instance);
          
            StationDic.Add(3,  UnloadStation.Instance);

            WorkStationBase.PauseEvent += WorkStationBase_PauseEvent;
            WorkStationBase.StopEvent += WorkStationBase_StopEvent;
           



            foreach (var station in StationDic.Values)
            {
                LogList.Add(station.LogModel);
                station.RegisterEvent();
                station.RetryEvent += Station_RetryEvent;
            }
         
       
            //注册事件
            RegisterEvent();

            EventAggregator.SubscribeOnUIThread(this);

           

            //注册状态机
            _fsm = new FSM(this,MainControlStation.Instance);
            RegisterState();
        }
       

        #endregion

        #region Event Handlers
        public void RegisterEvent()
        {
            SettingsViewModel.SetVelocityEvent += SettingsViewModel_SetVelocityEvent;
           // LoadStation.LoadBufferTrayChangedEvent += LoadStation_LoadBufferTrayChangedEvent;
            ShellViewModel.ClosingWindowEvent += ShellViewModel_ClosingWindowEvent;

            UnloadStation.Instance.UnloadFullEvent += UnloadStation_UnloadFullEvent;
            UnloadStation.Instance.UnloadEmptyEvent += Instance_UnloadEmptyEvent;

            CuttingStation.Instance.ClearDoneEvent += CuttingStation_ClearDoneEvent;

            CuttingStation.Instance.SingleCycleDoneEvent += Instance_SingleCycleDoneEvent;

            ProductViewModel.SaveEvent += ProductViewModel_SaveEvent;

            UnloadStation.Instance.UnloadNumberChangedEvent += UnloadStation_UnloadNumberChangedEvent;

            AutomaticSubModeChanged += HomeViewModel_AutomaticSubModeChanged;

            timer.Elapsed += Timer_Elapsed;

            ShellViewModel.ChangeLanguageEvent += ShellViewModel_ChangeLanguageEvent;

        }

        private void RegisterState()
        {
           
            _fsm.AddState(WorkStationStatus.Idle, new IdleState(_fsm));
            _fsm.AddState(WorkStationStatus.Stopped, new StoppedState(_fsm));
            _fsm.SwitchState(WorkStationStatus.Stopped);

        }

        private void ShellViewModel_ChangeLanguageEvent(LanguageEnum language)
        {
            foreach (var station in WorkStationDic.Values)
            {
                station.WorkStationName = LocalizationHelper.GetString(language, station.WorkStationKey);
                
            }

            foreach (var station in StationDic.Values)
            {
                station.LogModel.StationName = LocalizationHelper.GetString(language, station.StationKey);
            }
        }

        private void Instance_SingleCycleDoneEvent(bool isHeld)
        {
            IsSingleCycleHeld = isHeld;
        }

        private void HomeViewModel_AutomaticSubModeChanged(AutomaticSubMode mode)
        {
            AutomaticSubModeObservable = mode;

            if (mode != AutomaticSubMode.SingleStep)
            {
                foreach (var station in StationDic.Values)
                {

                    station.SingleStepCompleteEvent.Set();

                }
            }
        }

        private void ProductViewModel_SaveEvent(ProductModel obj)
        {
            StackMaxNumber = (double)ProductInfo.GetUnloadMaxNumber();
        }

        private void UnloadStation_UnloadNumberChangedEvent(uint count)
        {
            StackCount = count;
            ProductionCount= (uint)UnloadStation.UnloadCount;

            //更新数据库数据
            UpdateProductionData();
        }

        private void CuttingStation_ClearDoneEvent()
        {
            if (IsClearling)
            {
                IsClearling = false;
                ChangeClearButtonStyle(IsClearling);
            }


        }

        private async void Instance_UnloadEmptyEvent()
        {
            await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyTrayEmpty });
        }

        private async void UnloadStation_UnloadFullEvent()
        {
            await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyTrayFull});
        }

        private void Timer_Elapsed(object? sender, ElapsedEventArgs e)
        {
            ProductTimer = $"{_productTimerStopwatch.Elapsed.ToString(@"hh\:mm\:ss")}";
            TotalTimer = $"{_totalTimerStopwatch.Elapsed.ToString(@"hh\:mm\:ss")}";
          
            var totalHours = _productTimerStopwatch.Elapsed.TotalHours;
            OEE = (_productTimerStopwatch.Elapsed / _totalTimerStopwatch.Elapsed)*VeloctyRate *PassRate;
            UPH =(int)(UnloadStation.UnloadCount /totalHours);
        }


        /// <summary>
        /// 主控模块发过来的控制信号
        /// </summary>
        /// <param name="message"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async  Task HandleAsync(MainControlToHomeEvent message, CancellationToken cancellationToken)
        {
            if (message.MessageType== MessageType.NotifyStart)
            {
               bool res =  StartButtonIn();
                message.TaskCompletionSource.SetResult(res);
            }
            else if (message.MessageType== MessageType.NotifyStop)
            {
                var res =  StopButtonIn();
                message.TaskCompletionSource.SetResult(res);
            }
            else if (message.MessageType == MessageType.NotifyReset)
            {
                var res =await  ResetButtonIn();
                message.TaskCompletionSource?.SetResult(res);
            }
            else if (message.MessageType == MessageType.Manual)
            {
                Pause();
                message.TaskCompletionSource?.SetResult(true);
            }
            else if (message.MessageType == MessageType.Unsafty)
            {
                if (!IsInitialing && !isRunning)
                {                   
                    return;
                }

                if (isPause)
                {
                    return;
                }
                Pause();
                message.TaskCompletionSource?.SetResult(true);
            }
           
        }

        private async void ShellViewModel_ClosingWindowEvent()
        {
            await Stop();
        }

       
        /// <summary>
        /// 设置速度事件
        /// </summary>
        /// <param name="obj">速度值</param>
        private void SettingsViewModel_SetVelocityEvent(double obj)
        {
            double vel = obj / 100;
            //设置轴的速度
            foreach (var station in StationDic.Values)
            {
                foreach (var axis in station.AxisModels)
                {
                    axis?.MotionEntity?.SetVelocityRate(vel);
                }
            }

            //设置机器人速度
            foreach (var station in StationDic.Values)
            {
                foreach (var robot in station.RobotModels)
                {
                    robot?.Robot?.SetRobotVelRate(obj);
                }
            }


        }
        private void WorkStationBase_PauseEvent()
        {
            Pause();
        }
        private async void WorkStationBase_StopEvent(string? stopMessage = null,bool isSetAbortedStatus = true)
        {
            await Stop(stopMessage, isSetAbortedStatus);
        }

        

        private  MessageBoxResult Station_RetryEvent(string arg)
        {
            Logger.Warn(arg);

            
            var res = MessageBoxResult.No;
            Application.Current.Dispatcher.Invoke(() =>
            {
                 res = MessageBoxX.Show($"{arg}", "警告", MessageBoxButton.YesNo, MessageBoxIcon.Warning, DefaultButton.YesOK);
                
            });
            if (res == MessageBoxResult.Yes)
            {
                Pause();


                //通知正在重试
                //if (IsInitialing)
                //{
                //    SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyInitialResume }).GetAwaiter();
                //}
                //else
                //{
                //    SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyStart }).GetAwaiter();
                //}
            }
           



            return res;
        }
        #endregion

        #region Methods
        public async void GetAxis(int stationID)
        {
            //1.先判断是否有这个工位ID
            if (!_WorkStationDic.ContainsKey(stationID) || _WorkStationDic[stationID].AxisModels.Count < 1)
            {
                return;
            }

            //2.判断是不是窗口打开过
            if (_axisViewModelDic.Keys.Contains(stationID))
            {

                var window = GetWindow(_axisViewModelDic[stationID]);
                if (window != null)
                {
                    if (window.WindowState == WindowState.Minimized)
                    {
                        window.WindowState = WindowState.Normal;
                    }
                   // window.Activate();
                    window.Topmost = true;  // 确保窗口在最前面
                    window.Topmost = false; // 再次取消置顶
                }
                return;
            }

            //3.未打开则新增
            var axisViewModel = new AxisViewModel();
            _axisViewModelDic.Add(stationID, axisViewModel);



            //4.激活定时器刷新轴状态
            axisViewModel.Activated += ((o,e)=>
            {
                if (_WorkStationDic[axisViewModel.StationID] is null)
                {
                    return;
                }

                _WorkStationDic[axisViewModel.StationID].ActivedMotionMapping();

            });
            axisViewModel.Deactivated  += (async (o, e) =>
            {
                if (_WorkStationDic[axisViewModel.StationID] is null)
                {
                    return;
                }

                await Task.Delay(10);

                if (_axisViewModelDic.Keys.Contains(stationID))
                {
                    _axisViewModelDic.Remove(stationID);
                }

                _WorkStationDic[axisViewModel.StationID].DeactivedMotionMapping();

            });


            axisViewModel.AxisModelItems = _WorkStationDic[stationID].AxisModels;
            axisViewModel.StationID = stationID;

            



            await WindowManager.ShowWindowAsync(axisViewModel);
           
        }
      
        public void GetValves(int stationID)
        {
            if (!_WorkStationDic.ContainsKey(stationID) || _WorkStationDic[stationID].CylinderModels.Count < 1 )
            {
                return;
            }

            //2.判断是不是窗口打开过
            if (_valveViewModelDic.Keys.Contains(stationID))
            {
                var window = GetWindow(_valveViewModelDic[stationID]);
                if (window != null)
                {
                    if (window.WindowState == WindowState.Minimized)
                    {
                        window.WindowState = WindowState.Normal;
                    }
                   // window.Activate();
                    window.Topmost = true;  // 确保窗口在最前面
                    window.Topmost = false; // 再次取消置顶
                }
                return;
            }

            //3.未打开则新增
            var valveViewModel = new ValveViewModel();
            _valveViewModelDic.Add(stationID, valveViewModel);



            valveViewModel.Activated += ((o, e) =>
            {
                if (_WorkStationDic[valveViewModel.StationID] is null)
                {
                    return;
                }

                _WorkStationDic[valveViewModel.StationID].ActivedValveMapping();

            });
            valveViewModel.Deactivated += (async (o, e) =>
            {
                if (_WorkStationDic[valveViewModel.StationID] is null)
                {
                    return;
                }

                await Task.Delay(10);

                if (_valveViewModelDic.Keys.Contains(stationID))
                {
                    _valveViewModelDic.Remove(stationID);
                }

                _WorkStationDic[valveViewModel.StationID].DeactivedValveMapping();

            });

            valveViewModel.StationID = stationID;
            valveViewModel.CylinderModelItems = _WorkStationDic[stationID].CylinderModels;
            WindowManager.ShowWindowAsync(valveViewModel);
             

        }
     
        public void GetIODatas(int stationID)
        {
            if (!_WorkStationDic.ContainsKey(stationID) || _WorkStationDic[stationID].IOModels.Count<1)
            {
                return;
            }

            //2.判断是不是窗口打开过
            if (_iOViewModelDic.Keys.Contains(stationID))
            {
                var window = GetWindow(_iOViewModelDic[stationID]);
                if (window != null)
                {
                    if (window.WindowState == WindowState.Minimized)
                    {
                        window.WindowState = WindowState.Normal;
                    }
                   // window.Activate();
                    window.Topmost = true;  // 确保窗口在最前面
                    window.Topmost = false; // 再次取消置顶
                }
                return;
            }

            //3.未打开则新增
            var iOViewModel = new IOViewModel();
            _iOViewModelDic.Add(stationID, iOViewModel);


            iOViewModel.Activated += ((o, e) =>
            {
                if (_WorkStationDic[iOViewModel.StationID] is null)
                {
                    return;
                }

                _WorkStationDic[iOViewModel.StationID].ActivedIOMapping();

            });
            iOViewModel.Deactivated += (async (o, e) =>
            {
                if (_WorkStationDic[iOViewModel.StationID] is null)
                {
                    return;
                }

                await Task.Delay(10);

                if (_iOViewModelDic.Keys.Contains(stationID))
                {
                    _iOViewModelDic.Remove(stationID);
                }

                _WorkStationDic[iOViewModel.StationID].DeactivedIOMapping();

            });


            iOViewModel.StationID = stationID;
            iOViewModel.IOItems = _WorkStationDic[stationID].IOModels;
            WindowManager.ShowWindowAsync(iOViewModel);

        }

        public void GetStations(int stationID)
        {
            if (User !="Admin")
            {
                Toast.Show("当前用户权限不足！",targetWindow: ToastWindow.MainWindow);
                return;
            }
            if (!StationDic.ContainsKey(stationID))
            {
                return;
            }

            //2.判断是不是窗口打开过
            if (_StationSettingViewModelDic.Keys.Contains(stationID))
            {
                var window = GetWindow(_StationSettingViewModelDic[stationID]);
                if (window != null)
                {
                    if (window.WindowState == WindowState.Minimized)
                    {
                        window.WindowState = WindowState.Normal;
                    }
                  //  window.Activate();
                    window.Topmost = true;  // 确保窗口在最前面
                    window.Topmost = false; // 再次取消置顶
                }
                return;
            }

            //3.未打开则新增
            StationSettingViewModel model = new StationSettingViewModel();
            _StationSettingViewModelDic.Add(stationID, model);

            model.Deactivated += (async (o, e) =>
            {
               
                await Task.Delay(10);

                if (_StationSettingViewModelDic.Keys.Contains(stationID))
                {
                    _StationSettingViewModelDic.Remove(stationID);
                }

                

            });


            model.StationID = stationID;
            model.station = StationDic[stationID];
            model.StationName = StationDic[stationID].StationName;
            WindowManager.ShowWindowAsync(model);

        }

        public void GetPoints(int stationID)
        {
            if (!_WorkStationDic.ContainsKey(stationID) || _WorkStationDic[stationID].PointSettingModels.Count < 1)
            {
                return;
            }

            //2.判断是不是窗口打开过
            if (_pointsViewModelDic.Keys.Contains(stationID))
            {
                var window = GetWindow(_pointsViewModelDic[stationID]);
                if (window != null)
                {
                    if (window.WindowState == WindowState.Minimized)
                    {
                        window.WindowState = WindowState.Normal;
                    }
                  //  window.Activate();
                    window.Topmost = true;  // 确保窗口在最前面
                    window.Topmost = false; // 再次取消置顶
                }
                return;
            }

            //3.未打开则新增
            var PointsViewModel = new PointsViewModel();
            _pointsViewModelDic.Add(stationID, PointsViewModel);


            PointsViewModel.Deactivated += (async (o, e) =>
            {

                await Task.Delay(10);

                if (_pointsViewModelDic.Keys.Contains(stationID))
                {
                    _pointsViewModelDic.Remove(stationID);
                }



            });




            PointsViewModel.StationID = stationID;
            PointsViewModel.PointSettingModelItems = _WorkStationDic[stationID].PointSettingModels;
            WindowManager.ShowWindowAsync(PointsViewModel);

        }

        public void GetCoordinate(int stationID)
        {
            if (!_WorkStationDic.ContainsKey(stationID) || _WorkStationDic[stationID].CoordinateModels.Count < 1)
            {
                return;
            }


            //2.判断是不是窗口打开过
            if (_pointsViewModelDic.Keys.Contains(stationID))
            {
                var window = GetWindow(_pointsViewModelDic[stationID]);
                if (window != null)
                {
                    if (window.WindowState == WindowState.Minimized)
                    {
                        window.WindowState = WindowState.Normal;
                    }
                   // window.Activate();
                    window.Topmost = true;  // 确保窗口在最前面
                    window.Topmost = false; // 再次取消置顶
                }
                return;
            }

            //3.未打开则新增
            var coordinateViewModel = new CoordinateViewModel();
            _coordinateViewModelDic.Add(stationID, coordinateViewModel);




            coordinateViewModel.Activated += ((o, e) =>
            {
                if (_WorkStationDic[coordinateViewModel.StationID] is null)
                {
                    return;
                }

                _WorkStationDic[coordinateViewModel.StationID].ActivedCoordianteMapping();

            });
            coordinateViewModel.Deactivated += (async (o, e) =>
            {
                if (_WorkStationDic[coordinateViewModel.StationID] is null)
                {
                    return;
                }

                await Task.Delay(10);

                if (_coordinateViewModelDic.Keys.Contains(stationID))
                {
                    _coordinateViewModelDic.Remove(stationID);
                }


                _WorkStationDic[coordinateViewModel.StationID].DeactivedCoordinateMapping();

            });


            coordinateViewModel.StationID = stationID;
            coordinateViewModel.CoordinateModelItems = _WorkStationDic[stationID].CoordinateModels;
            WindowManager.ShowWindowAsync(coordinateViewModel);
        }

        public void GetProduct()
        {
            ProductViewModel productViewModel = new ProductViewModel();
            WindowManager.ShowWindowAsync(productViewModel);
        }

        public void GetDxf()
        {
            WindowManager.ShowWindowAsync(CADViewModel);
        }


        private Window? GetWindow(object viewModel)
        {
            foreach (Window window in Application.Current.Windows)
            {
                if (window.DataContext == viewModel)
                {
                    return window;
                }
            }
            return null;
        }

        #endregion

        #region MainControl
        public async  void Initial()
        {

            //1.先判断急停是否旋回,是否报警，是否属于自动模式
            if (IsEstopStatus() || IsAbortedStatus() || !await IsAutoMode())
            {
                return;
            }
           


            //2.警告
            var MsResult = MessageBoxX.Show("是否重新初始化？", "警告", MessageBoxButton.YesNo, MessageBoxIcon.Warning, DefaultButton.YesOK);
            if (MsResult != MessageBoxResult.Yes)
            {
                return;
            }

           
            //3.提示
            if (isRunning)
            {
                Toast.Show("请先停止运行！", targetWindow: ToastWindow.MainWindow);
                return;
            }
            else if (IsInitialing)
            {
                Toast.Show("初始化中...", targetWindow: ToastWindow.MainWindow);
                return;
            }

            //5.初始化中

            Initialing();


        }

        public async void Start()
        {
            //1.先判断急停是否旋回,是否报警，是否属于自动模式
            if (IsEstopStatus() || IsAbortedStatus() || !await IsAutoMode() || !IsInitialStatus())
            {
                return;
            }


          
            //2.如果正在初始化或运行中，直接停机

            if (IsInitialing || isRunning)
            {
                await Stop();
                return;
            }



         
            //3.运行
            try
            {
                StartRunning();
            }
            catch (Exception e)
            {
                MessageBoxX.Show(e.Message);
                return;
            }

            
        }

        public async  void Pause()
        {
            try
            {

                //1.是否有错误
                if (IsAbortedStatus() || !IsInitialingOrRunning())
                {
                    return;
                }



                //2.恢复运行逻辑

                if (isPause)
                {
                    if (!await IsAutoMode())
                    {
                        return;
                    }

                    if (IsInitialing)
                    {
                        SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyInitialResume }).GetAwaiter();
                    }
                    ResumeRunning();
                    return;
                }



                //3.暂停逻辑
                 PauseRunning();

             
            }
            catch (Exception)
            {

                throw;
            }
           
            
        }

        public void Clear()
        {
            IsClearling = !IsClearling;
            ChangeClearButtonStyle(IsClearling);

            List<Task> tasks = new List<Task>();
            foreach (var station in StationDic.Values)
            {
               // tasks.Add(station.Clear());
                 station.IsClear = IsClearling;
            }

            //ClearEvent?.Invoke(IsClearling,ClearTimes);
        }
       
        public async void Reset()
        {
            

            await ResetAsync();


        }

        public async Task<bool> ResetAsync()
        {
            //1.先判断急停是否旋回
            if (IsEstopStatus())
            {
                return false;
            }

            //2.复位错误
            foreach (var station in StationDic.Values)
            {
                if (station.LogModel.Status == WorkStationStatus.Aborted)
                {
                    await station.Reset();

                }
            }

            await SendAsync(new HomeToMainControlEvent() { MessageType=MessageType.NotifyReset});

            return true;

        }

        public async Task Stop(string? stopMessage = null,bool isSetAbortedStatus = true)
        {
            
            _productTimerStopwatch.Stop();
            timer.Stop();
            List<Task> tasks = new List<Task>();
            foreach (var station in StationDic.Values)
            {
                tasks.Add(station.Stop(stopMessage,  isSetAbortedStatus));
               // await Task.Run(() => station.Stop());

            }
            await Task.WhenAll(tasks);
            isRunning = false;

            isPause = false;

            await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyStop });

            ChangePauseButtonStyle(isPause);
            ChangeStartButtonStyle(isRunning);
        }
      

        public  bool StartButtonIn()
        {

            //1.先判断急停是否旋回
            if (IsEstopStatus() || IsAbortedStatus() || !IsInitialStatus())
            {
                return false;
            }

     
            //2.如果中途有暂停，先恢复暂停
            if ((isRunning || IsInitialing) && isPause)
            {                
                ResumeRunning();
                return true;
            }
            else if (isRunning)
            {
                return false;
            }

            //3.启动
            try
            {
                StartRunning();
            }
            catch (Exception e)
            {
                MessageBoxX.Show(e.Message);
                return false;
            }


            return true;
        }

        public  bool StopButtonIn()
        {
            try
            {
                //1.查看是否错误,是否暂停中，是否已经初始化
                if (IsAbortedStatus() || isPause || (!IsInitialing && !IsInitialStatus()))
                {
                    return false;
                }

                //2.暂停
                PauseRunning();
            }
            catch (Exception)
            {

                throw;
            }
           

            return true;
        }


        public async Task<bool> ResetButtonIn()
        {
            return await ResetAsync();
    
        }


        public void Next()
        {
            foreach (var station in StationDic.Values)
            {

                station.NextStep();

            }

            if (AutomaticSubMode is AutomaticSubMode.SingleCycle && IsSingleCycleHeld)
            {
                CuttingStation.Instance.NextCycle();
            }
        }

        #endregion

        #region Private Methods


        public void UpdateProductionData()
        {
            var productionData = new ProductionDataContext();
            ProductionDataModel productionMode = new ProductionDataModel()
            {

                StartTime = _startTime,
                ProductionType = ProductionType,
                Operator = User,
                MachineUpTime = _totalTimerStopwatch.Elapsed,
                ProductionTime = _productTimerStopwatch.Elapsed,
                DownTime = _totalTimerStopwatch.Elapsed - _productTimerStopwatch.Elapsed,
                Output = (int)ProductionCount,
                OEE = OEE,
                UPH = UPH,
                Yield = PassRate,
                LastUpdated = System.DateTime.Now,
            };

            productionData.Update(productionMode);


        }

        /// <summary>
        /// 发送请求
        /// </summary>
        /// <param name="request">请求信息</param>
        /// <returns></returns>
        public async Task<bool> SendAsync(EventBase? request)
        {
           
            if (request is null)
            {
                return false;
            }
            await EventAggregator.PublishOnUIThreadAsync(request);
            return await request.TaskCompletionSource.Task;
        }

        private  void ChangeStartButtonStyle(bool runOrNot)
        {          
            StartButtonModel.Content = runOrNot ? "停止" : "启动";
            StartButtonModel.BackBrush = runOrNot ? Brushes.Pink : Brushes.LightGreen;

        }

        private void ChangeClearButtonStyle(bool runOrNot)
        {
            ClearButtonModel.Content = runOrNot ? "取消清料" : "清料";
            ClearButtonModel.BackBrush = runOrNot ? Brushes.Gray : Brushes.LightBlue;           

        }

        private  void ChangePauseButtonStyle(bool runOrNot)
        {
            //if (runOrNot)
            //{
            //    await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyPause });
            //}
            //else if (!runOrNot && IsInitialing)
            //{
            //    await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyInitialResume }); 
              
            //}
            //else
            //{
            //    await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyResume });
            //} 

            PauseButtonModel.Content = runOrNot ? "继续" : "暂停";
            PauseButtonModel.BackBrush = runOrNot ? Brushes.LightCyan : Brushes.Orange;

        }



        #endregion

        #region Utility
    
        public bool IsInitialingOrRunning()
        {
            if (!IsInitialing && !isRunning)
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    Toast.Show("未在运行！", targetWindow: ToastWindow.MainWindow);
                });

                return false;
            }

            return true;
        }
        public async Task<bool> IsAutoMode()
        {
          bool res=   await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.RequestAuto });
            if (!res)
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    MessageBoxX.Show("请打到自动模式！！");
                });
            }
            
            return res;
        }
        public bool IsAbortedStatus()
        {
            foreach (var station in StationDic.Values)
            {
                if (station.LogModel.Status == WorkStationStatus.Aborted)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        MessageBoxX.Show("请先复位错误！");
                    });
                    return true;
                }
            }
            return false;
        }

        public bool IsInitialStatus()
        {
            foreach (var station in StationDic.Values)
            {
                if (station.LogModel.Status == WorkStationStatus.Stopped && !IsInitialed)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        MessageBoxX.Show("请先初始化！");
                    });

                    return false;
                }
            }

            //if (!IsInitialed)
            //{
            //    Application.Current.Dispatcher.Invoke(() =>
            //    {
            //        MessageBoxX.Show("请先初始化！");
            //    });
            //    return false;
            //}

            return true;
        }

        public async void ResumeRunning()
        {
            foreach (var station in StationDic.Values)
            {
                (bool result,string name,string value) = station.ResumnBeforeCheckStatus();


                if (!result)
                {
                    Application.Current.Dispatcher.Invoke(() =>
                    {
                        MessageBoxX.Show($"{name}不在暂停前位置:{value},禁止启动!", "警告！", icon: MessageBoxIcon.Warning);
                    });
                   
                    return;
                }
               
            }


            _productTimerStopwatch.Start();
            isPause = false;
            List<Task> taskL = new List<Task>();
            foreach (var station in StationDic.Values)
            {
                taskL.Add(station.Resume());
                isResuming = true;

            }
          
           ChangePauseButtonStyle(isPause);
            await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyResume });

            isResuming = false;
        }

        public async  void PauseRunning()
        {
            try
            {
                //暂停逻辑
               
                _productTimerStopwatch.Stop();
                isPause = true;
                List<Task> tasks = new List<Task>();
                foreach (var station in StationDic.Values)
                {
                    tasks.Add(station.Pause());
                   

                }
                await Task.WhenAll(tasks);

                ChangePauseButtonStyle(isPause);

                await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyPause });
            }
            catch (Exception)
            {

                throw;
            }
           
        }

        public async  void StartRunning()
        {
            isRunning = true;
            _totalTimerStopwatch.Restart();
            _productTimerStopwatch.Restart();
            timer.Start();
            ChangeStartButtonStyle(isRunning);

            await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyStart });

            var cts = new CancellationTokenSource();    

            foreach (var station in StationDic.Values)
            {

                station.CancellationTokenSource = cts;

            }


            _startTime = DateTime.Now;

            try
            {
                await Task.Run(() =>
                {
                    StationDic[1].DryRun();
                });
               

                //List<Task> tasks = new List<Task>
                //{
                //    StationDic[1].DryRun()
                //};


            }
            catch (Exception)
            {
                
                throw;
            }
        }

        public bool IsEstopStatus()
        {
            var res = ResetEvent?.Invoke();
            if (res != null && (bool)res)
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    MessageBoxX.Show("急停按钮未旋回！");
                });
               
                return true;
            }

            res = SafetyOptpEvent?.Invoke();
            if (res != null && (bool)res)
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    MessageBoxX.Show("龙门防撞光电触发未解除！");
                });

                return true;
            }

            return false;
        }

        public async void Initialing()
        {
            IsInitialing = true;
            IsInitialed = false;
            //通知正在初始化
            await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.Initial });
            IsClearling = false;
            ClearTimes = 0;
            //刷新清理按钮
            ChangeClearButtonStyle(IsClearling);

            ////刷新初始化按钮
            ChangeStartButtonStyle(IsInitialing);

            //复位定时器
            _productTimerStopwatch.Reset();
           

            // 创建一个 CancellationTokenSource
            var cancellationTokenSource = new CancellationTokenSource();
            var manualResetEvent = new ManualResetEvent(true);
            try
            {
                await Task.Run(async () =>
                {
                    foreach (var station in StationDic.Values)
                    {
                        station.CancellationTokenSource = cancellationTokenSource;

                    }


                    await MainControlStation.Instance.Initial();
                    await LoadStation.Instance.Initial();
                    await CuttingStation.Instance.Initial();
                    await UnloadStation.Instance.Initial();

                    IsInitialing = false;
                    IsInitialed = true;
                    

                    await SendAsync(new HomeToMainControlEvent() { MessageType = MessageType.NotifyIdle });
                });
               

              

                //设置整机速度
                
                ChangeStartButtonStyle(IsInitialing);
                Toast.Show("初始化完成！", targetWindow: ToastWindow.MainWindow);

            }
            catch (Exception)
            {
                IsInitialing = false;
                ChangeStartButtonStyle(IsInitialing);
                await Stop();
                return;
            }
        }


        #endregion



    }
}
